using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace DataTransformationTasks.BaseDriver;

public static class Bootstrap
{
    public static Task<dynamic> Start(string[] args)
    {
        DetectArch();
        var configFiles = GetArgument(args, "--config", "config.system.yml,config.user.yml,config.machines.yml");
        var config = ReadConfig(configFiles.Split(','));
        return Task.FromResult(config);
    }

    private static void DetectArch()
    {
        LoggerFactory.CreateLogger(typeof(Bootstrap)).LogInformation($"Bitness: {(IntPtr.Size == 8 ? "64-bit" : "32-bit")}");
    }

    private static string GetArgument(string[] args, string optionName, string defaultValue)
    {
        var value = args.SkipWhile(i => i != optionName).Skip(1).Take(1).FirstOrDefault();
        var optionValue = string.IsNullOrEmpty(value) ? defaultValue : value;
        LoggerFactory.CreateLogger(typeof(Bootstrap)).LogInformation($"Argument '{optionName}' = '{optionValue}'");
        return optionValue;
    }

    private static dynamic ReadConfig(string[] configFiles)
    {
        var stringBuilder = new StringBuilder();

        foreach (var configFile in configFiles)
        {
            stringBuilder.Append(File.ReadAllText(configFile));
        }

        var stringReader = new StringReader(stringBuilder.ToString());
        var parser = new Parser(stringReader);
        var mergingParser = new MergingParser(parser);

        var deserializer = new DeserializerBuilder()
            .WithNamingConvention(CamelCaseNamingConvention.Instance)
            .Build();

        var config = deserializer.Deserialize(mergingParser);

        LoggerFactory.CreateLogger(typeof(Bootstrap)).LogTrace($"Deserialized configuration:\n{JsonSerializer.Serialize(config ?? new { })}");

        return config;
    }
}